package com.atguigu.gmall.publisher.service.impl;

import com.atguigu.gmall.publisher.service.DauService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateUtils;
import org.elasticsearch.ElasticsearchStatusException;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.terms.ParsedStringTerms;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class DauServiceImpl implements DauService {

    @Autowired
    RestHighLevelClient restHighLevelClient;

    private final String indexNamePrefix="gmall0701_dau_info_";


    //{ dauTotal:123,
    //   dauYd:{"12":90,"13":33,"17":166 },
    //   dauTd:{"11":232,"15":45,"18":76}
    //}
    @Override
    public Map getDauRealtime(String today) {
        Map dauMap=new HashMap();
        Long dauTotal = getDauTotal(today);

        dauMap.put("dauTotal",dauTotal);
        Map dauTodayMap= getDauHourMap(today);

        String yd = getYd(today);
        Map dauYesterdayMap= getDauHourMap(yd);

        dauMap.put("dauYd",dauYesterdayMap);
        dauMap.put("dauTd",dauTodayMap);

        return dauMap;
    }


    private  Long getDauTotal( String today){
        String indexName=indexNamePrefix+today;
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.fetchSource("","");
        searchSourceBuilder.size(0);
        SearchRequest searchRequest = new SearchRequest(indexName).source(searchSourceBuilder);
        try {
            SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
            long total = searchResponse.getHits().getTotalHits().value;
            return total;
        } catch (ElasticsearchStatusException ese){
              if(ese.status()== RestStatus.NOT_FOUND){
                  log.warn("索引 未建立："+ese.getIndex());
                  return 0L;
              }
              throw new RuntimeException("es 查询异常");
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException("es 连接异常");
        }

    }



   private   Map  getDauHourMap(String date){
        //1 组织查询条件
       String indexName=indexNamePrefix+date;
       SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
       searchSourceBuilder.size(0);

       TermsAggregationBuilder hrAgg = AggregationBuilders.terms("groupby_hr").field("hr").size(24);
       searchSourceBuilder.aggregation(hrAgg);

       SearchRequest searchRequest = new SearchRequest(indexName).source(searchSourceBuilder);

       try {
           //2 执行查询
           SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
           //3 提取查询结果
           ParsedStringTerms hrTerms = searchResponse.getAggregations().get("groupby_hr");
           List<? extends Terms.Bucket> buckets = hrTerms.getBuckets();
           Map dauHourMap=new HashMap();
           for (Terms.Bucket bucket : buckets) {
               dauHourMap.put( bucket.getKey(),bucket.getDocCount());
           }
           return dauHourMap;

       } catch (ElasticsearchStatusException ese){
           if(ese.status()== RestStatus.NOT_FOUND){
               log.warn("索引 未建立："+ese.getIndex());
               return  new HashMap();
           }
           throw new RuntimeException("es 查询异常");
       } catch (IOException e) {
           e.printStackTrace();
           throw new RuntimeException("es 连接异常");
       }


   }


   private  String getYd(String td){
       SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");

       try {
           Date tdDate = simpleDateFormat.parse(td);
           Date ydDate = DateUtils.addDays(tdDate, -1);
           String yd = simpleDateFormat.format(ydDate);
           return yd;

       } catch (ParseException e) {
           e.printStackTrace();
           throw new RuntimeException("日期格式有误 ");
       }


   }
}
